package com.example.demo.service.impl;

import com.example.demo.common.convention.exception.ClientException;
import com.example.demo.common.convention.result.Result;
import com.example.demo.dao.entity.Captcha;
import com.example.demo.service.CaptchaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static com.example.demo.common.convention.errorcode.BaseErrorCode.*;

@Slf4j
@Service
public class CaptchaServiceImpl implements CaptchaService {

    private final Map<String, Captcha> CaptchaStorage = new ConcurrentHashMap<>();


    @Override
    public DeferredResult<Object> getCaptcha(String userId) {
        DeferredResult<Object> deferredResult = new DeferredResult<>((long) 70000);
        Captcha captcha = new Captcha();
        CaptchaStorage.put(userId, captcha);
        new Thread(() -> {
            String code;
            synchronized (captcha) {
                while (captcha.getNewCaptcha()==null||!captcha.getNewCaptcha())
                {
                    try {
                        captcha.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                code = captcha.getCode();
            }
            Map<String, Object> map = new HashMap<>();
            map.put("code", code);
            // 如果超过尝试次数，返回超时错误
            Result<Map<String, Object>> result = new Result<Map<String, Object>>()
                    .setCode("0")
                    .setData(map)
                    .setMessage("请求超时");
            deferredResult.setResult(result);
        }).start();

        // 处理超时
        deferredResult.onTimeout(() -> {
            Result<String> result = new Result<String>()
                    .setCode("1")
                    .setMessage("请求超时");
            deferredResult.setResult(result);
        });

        return deferredResult;

    }

    @Override
    public void postCaptcha(String userId, String code) {
        Captcha captcha = CaptchaStorage.get(userId);
        if (captcha != null) {
            synchronized (captcha) {
                if (captcha.getNewCaptcha()==null||!captcha.getNewCaptcha())
                {
                    // 验证验证码是否正确
                    captcha.setCode(code);
                    // 更新验证码状态为已使用
                    captcha.setNewCaptcha(true);
                    captcha.notify();
                }
                else {
                    throw new ClientException(CAPTCHA_USED_ERROR);
                }
            }
        }
        else {
            throw new ClientException(CAPTCHA_USER_NULL_ERROR);
        }
    }
    @Override
    public DeferredResult<Object> getCaptchaResult(String userId) {
        Captcha captcha = CaptchaStorage.get(userId);
        DeferredResult<Object> deferredResult = new DeferredResult<>((long) 70000);
        new Thread(() -> {
            String status;
            synchronized (captcha) {
                while (captcha.getStatus()==null) {
                    try {
                        captcha.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                status = captcha.getStatus();
                CaptchaStorage.remove(userId);
            }
            Map<String, Object> map = new HashMap<>();
            map.put("status", status);
            // 如果超过尝试次数，返回超时错误
            Result<Map<String, Object>> result = new Result<Map<String, Object>>()
                    .setCode("0")
                    .setData(map)
                    .setMessage("请求成功");
            deferredResult.setResult(result);
        }).start();

        // 处理超时
        deferredResult.onTimeout(() -> {
            Result<String> result = new Result<String>()
                    .setCode("1")
                    .setMessage("请求超时");
            deferredResult.setResult(result);
        });

        return deferredResult;

    }

    @Override
    public void postCaptchaResult(String userId, String status) {
        Captcha captcha = CaptchaStorage.get(userId);

        if (captcha != null) {
            synchronized (captcha) {
                if (captcha.getNewCaptcha()) {
                    captcha.setStatus(status);
                    captcha.notify();
                }
                else {
                    throw new ClientException(CAPTCHA_NOT_USED_ERROR);
                }
            }
        }
        else {
            throw new ClientException(CAPTCHA_USER_NULL_ERROR);
        }
    }
}
